import { Card, Modal, Table, Timeline, Spin, TimelineItemProps, Empty } from "antd"
import React, { FC, memo, ReactNode, useState } from "react"
import { CheckCircleOutlined, CloseCircleOutlined } from "@ant-design/icons"
import { getErrorListService } from "@/service/error"
import { useRequest } from "ahooks"
import dayjs from "dayjs"
import type { ErrorInfoType, BehaviorType, newLinesType } from "./type"
import ListPage from "@/components/ListPage"
import { useSearchParams } from "react-router-dom"
import { LIST_PAGE_PARAM_KEY, LIST_PAGE_SIZE, LIST_PAGE_SIZE_PARAM_KEY } from "@/constant"
import styles from "./index.module.scss"
import { findCodeBySourchMap } from "@/utils/sourcemap"
import classNames from "classnames"
import parse from "html-react-parser"
import FullscreenModal from "@/components/FullscreenModal"
import Player from "../Player"

const ErrorList: FC = () => {
    const [isModalVisible, setIsModalVisible] = useState(false)
    const [isFullModalVisible, setIsFullModalVisible] = useState(false)
    const [modalContent, setModalContent] = useState<ReactNode>(null)
    const [modalTitle, setModalTitle] = useState("")
    const [searchParams] = useSearchParams()

    //#region 发送网络请求
    async function getErrorData() {
        // 获取page关键词（要一个数字类型）
        const page = parseInt(searchParams.get(LIST_PAGE_PARAM_KEY) || "") || 1
        // 获取分页大小关键词（当前页有多少条数据）
        const pageSize = parseInt(searchParams.get(LIST_PAGE_SIZE_PARAM_KEY) || "") || LIST_PAGE_SIZE

        const data = await getErrorListService({ page, pageSize })
        return data
    }

    const { loading: eLoading, data: eData = {} } = useRequest(getErrorData, {
        refreshDeps: [searchParams] // 依赖性，searchParams更新，数据就刷新
    })
    const { count = 0, list = [] } = eData
    //#endregion

    //#region 构造用户行为的数据列表
    function genBehaviorList(behaviorTimeLine: BehaviorType[]): TimelineItemProps[] {
        return behaviorTimeLine.map((item: BehaviorType) => {
            // 根据状态设置颜色和图标
            const color = item.status === "ok" ? "green" : "red"
            const icon = item.status === "ok" ? <CheckCircleOutlined style={{ fontSize: "16px" }} /> : <CloseCircleOutlined style={{ fontSize: "16px" }} />

            // 根据 category 设置内容
            let content: ReactNode
            if (item.category === "Click") {
                content = `用户点击dom: ${item.dom}`
            } else if (item.category === "Resource_Error") {
                content = `加载资源报错: ${item.message}`
            } else if (item.category === "Route") {
                content = `路由变化：从 ${item.from}页面 切换到 ${item.to}页面`
            } else {
                content = `未知行为类型：${item.category}`
            }

            // 返回 Timeline.Item 所需的格式
            return {
                dot: icon, // 图标
                color, // 颜色
                children: (
                    <div>
                        <p>{content}</p>
                        <p>{new Date(item.time).toLocaleString()}</p>
                    </div>
                )
            }
        })
    }
    //#endregion

    async function handleViewSource(record: ErrorInfoType) {
        setModalTitle("查看源码")
        console.log(record)

        // setModalContent(<div>源码内容：{record.errorInfo}</div>)

        // 检查必要的字段是否存在
        if (!record.fileName || !record.line || !record.column) {
            console.error("缺少必要的错误信息字段：", record)
            return
        }

        const { source, row, column, newLines } = (await findCodeBySourchMap({
            fileName: record.fileName,
            line: record.line,
            column: record.column
        })) as {
            source: string
            row: number
            column: number
            newLines: newLinesType[]
        }

        // const errorCode = newLines.map((item, index) => <Fragment key={index}> {parse(item)}</Fragment>)
        const errorCode = newLines.map((item: any, index: number) => {
            const className = classNames(styles["code-line"], { [styles.heightlight]: item.start + 1 + index === row })
            return (
                <div className={className} key={index} title={item.start + 1 + index === row ? source : ""}>
                    {item.j}. {parse(item.replaceContent)}
                </div>
            )
        })
        const content = (
            <div className={styles.errdetail}>
                <div className={styles.errheader}>
                    {source} at line {row}:{column}
                </div>
                {errorCode}
            </div>
        )
        setModalContent(content)
        setIsModalVisible(true)
    }

    async function handlePlayRecording(record: ErrorInfoType) {
        setModalTitle("播放录屏")
        setModalContent(<Player recordScreenId={record.recordScreenId} />)
        setIsFullModalVisible(true)
    }

    function handleViewBehavior(record: ErrorInfoType) {
        setModalTitle("查看用户行为")
        setModalContent(<div style={{ padding: "40px 0 0 80px" }}>{<Timeline items={genBehaviorList(record.behavior)} />}</div>)
        setIsModalVisible(true)
    }

    //#region 列表配置
    const columns = [
        {
            title: "报错信息",
            dataIndex: "message"
        },
        {
            title: "报错页面路由",
            dataIndex: "pageUrl"
        },
        {
            title: "报错时间",
            dataIndex: "time",
            render: (value: number) => dayjs(value).format("YYYY-MM-DD HH:mm:ss")
        },
        {
            title: "错误类型",
            dataIndex: "errorType"
        },
        {
            title: "用户id",
            dataIndex: "userId"
        },
        {
            title: "AppId",
            dataIndex: "appId"
        },
        {
            title: "浏览器信息",
            dataIndex: "browser",
            render: (_: any, record: ErrorInfoType) => record.deviceInfo.browser // 手动访问嵌套字段
        },
        {
            title: "操作系统",
            // 访问嵌套字段
            dataIndex: "os",
            render: (_: any, record: ErrorInfoType) => record.deviceInfo.os // 手动访问嵌套字段
        },
        {
            title: "还原错误代码",
            key: "restoreCode",
            render: (_: string, record: ErrorInfoType) => {
                // 如果 record.type === "resource"，不显示按钮
                if (record.errorType === "resourceError") {
                    return null // 返回 null 表示不渲染任何内容
                }
                return (
                    <a style={{ fontSize: "12px" }} onClick={() => handleViewSource(record)}>
                        查看源码
                    </a>
                )
            }
        },
        {
            title: "播放录屏",
            key: "playback",
            render: (_: string, record: ErrorInfoType) => (
                <a style={{ fontSize: "12px" }} onClick={() => handlePlayRecording(record)}>
                    播放录屏
                </a>
            )
        },
        {
            title: "用户行为记录",
            key: "userActions",
            render: (_: string, record: any) => (
                <a style={{ fontSize: "12px" }} onClick={() => handleViewBehavior(record)}>
                    查看用户行为
                </a>
            )
        }
    ]
    //#endregion

    return (
        <>
            <Card title="异常错误信息" variant="borderless">
                <Spin spinning={eLoading}>
                    {!eLoading && list.length === 0 && <Empty description="暂无数据" />}
                    {list.length > 0 && (
                        <>
                            <Table dataSource={list} pagination={false} columns={columns} rowKey={(q: any) => q._id} />
                            <div style={{ marginTop: "20px" }}>
                                <ListPage total={count} />
                            </div>
                        </>
                    )}
                </Spin>
            </Card>
            <Modal width="900px" destroyOnClose title={modalTitle} footer={null} open={isModalVisible} onCancel={() => setIsModalVisible(false)}>
                {modalContent}
            </Modal>
            <FullscreenModal isOpen={isFullModalVisible} onClose={() => setIsFullModalVisible(false)} title={modalTitle}>
                {/* <div style={{ display: "flex", justifyContent: "center", alignItems: "center", paddingTop: "-24px" }} ref={videoRef} /> */}
                {modalContent}
            </FullscreenModal>
        </>
    )
}

export default memo(ErrorList)
